#!/usr/bin/env python
# public/upload_news.py
# -*- coding: utf-8 -*-
"""
推送文章到微信公众号
"""

import sys
from pathlib import Path

import click
from loguru import logger

from mdtool.commands.at_commander import AtCommander
from mdtool.config_reader import load_yaml_config
from mdtool.markdown_document import MarkdownDocument
from mdtool.publish.wx_publisher import WxPublisher
from mdtool.wx_cache import WxCache

logger.remove()  # 移除所有已存在的 handler，防止重复
logger.add(sys.stderr, level="INFO")
cache = None
wx_publisher = None

ACTION_HELP_MAP = {
    "check": "检查最近一周内修改的文件格式\n",
    "checkall": "检查所有文件格式\n",
    "publish": "发布文章（默认）\n",
    "imglist": "获取公众号图片列表\n",
    "draft": "获取草稿列表\n",
    "nodraft": "获取非草稿列表\n",
    "rm_dup": "删除重复图片\n",
    "save_to_feishu": "将最新发布的文章更新到飞书的表单中\n",
}


def get_action_help_text():
    return "\n".join([f"  {k:<15} {v}" for k, v in ACTION_HELP_MAP.items()])


def upload_media_news(wx_publisher, md_doc):
    media_id = wx_publisher.publish_single_article(md_doc)
    if not media_id:
        logger.error(f"上传失败：{md_doc.abs_path}")
        return None
    return media_id


def check_format(md_files, source_dir) -> list:
    print("\n开始检查格式...")
    invalid_list = []
    for md_file in md_files:
        logger.debug(f"\n检查文件：{md_file}")
        if not check_single_format(str(md_file), source_dir):
            invalid_list.append(str(md_file))
    return invalid_list


def check_single_format(abs_path, source_dir) -> bool:
    relative_path = Path(abs_path).relative_to(source_dir)
    try:
        md_doc = MarkdownDocument.from_file(str(relative_path), source_dir)
        ret = md_doc.check_format()
        if len(ret) > 0:
            logger.warning(f"Error: {ret}")
            logger.debug(f"Error: {ret}")
            return False
        return True
    except Exception as e:
        logger.debug(f"Error: {e}")
        return False


def run(config) -> bool:
    cache = WxCache(config)
    wx_publisher = WxPublisher(cache, config)
    source_dir = config.get("articledir")
    pathlist = list(Path(source_dir).glob("**/*.md"))
    # 从pathlist 中排除 history_json 目录下的 .md 文件
    pathlist = [
        path
        for path in pathlist
        if not Path(path).relative_to(source_dir).match("history_json/**/*.md")
    ]
    total = len(pathlist)
    cachefiles = []
    uploadfiles = []
    errorfiles = []
    draftfiles = []
    count = 0
    for path in pathlist:
        if cache.is_cached(str(path)):
            logger.debug("{} has been processed".format(str(path)))
            cachefiles.append(str(path))
            count += 1
            continue
        else:
            relative_path = Path(path).relative_to(source_dir)
            md_doc = MarkdownDocument.from_file(str(relative_path), source_dir)
            if md_doc.is_draft():
                draftfiles.append(str(path))
                continue
            if not upload_media_news(wx_publisher, md_doc):
                logger.warning(f"操作出错：{str(path)}")
                errorfiles.append(str(path))
            else:
                uploadfiles.append(str(path))
                logger.info(f"上传成功：{str(path)}")
                count += 1
    logger.debug(f"共计处理 {total} 篇文章")
    logger.debug(f"已  缓存 {len(cachefiles)} 篇")
    logger.debug(f"   草稿 {len(draftfiles)} 篇")
    logger.debug(f"成功上传 {len(uploadfiles)} 篇")
    logger.debug(f"上传失败 {len(errorfiles)} 篇")
    return count == total


def delete_duplicate_images(config):
    cache = WxCache(config)
    cache.remove_duplication(cache.find_cached_imgs_with_duplication())
    pass


def get_draft_list(source_dir, is_draft: bool = True):
    """
    获取草稿列表

    Returns:
        list: 包含草稿箱中所有文章信息的列表,每个元素为一个字典,包含文件名、文章标题信息
    """
    pathlist = list(Path(source_dir).glob("**/*.md"))
    draft_list = []
    for path in pathlist:
        relative_path = Path(path).relative_to(source_dir)
        md_doc = MarkdownDocument.from_file(str(relative_path), source_dir)

        if (is_draft and md_doc.is_draft()) or (not is_draft and not md_doc.is_draft()):
            # if not md_doc.is_draft():
            draft_list.append(
                {"filename": str(relative_path), "title": md_doc.title})
    # 打印 draft_list
    print(f"{len(draft_list)} 篇，列表：")
    for draft in draft_list:
        print(f"文件名：{draft['filename']}, \t标题：{draft['title']}")
    return draft_list


def main(input_func=input) -> int | None:
    @click.command()
    @click.option(
        "--config-file",
        "-c",
        help="系统配置文件，是一个 YAML 格式的配置文件，用于指定微信公众号的配置信息",
        required=True,
    )
    @click.option(
        "--action",
        "-a",
        type=click.Choice(list(ACTION_HELP_MAP.keys())),
        default="publish",
        show_default=True,
        help=f"执行的操作：\n\n{get_action_help_text()}",
    )
    @click.version_option("0.1.1")
    def cli(config_file, action):
        click.echo(f"当前操作: {action} - {ACTION_HELP_MAP[action]}")
        config = load_yaml_config(config_file)
        commander = AtCommander(config)
        commander.execute(action, config)

    cli()
    return 0


if __name__ == "__main__":
    exit(main())
